﻿#pragma execution_character_set("utf-8")

#include "lunarcalendaritem.h"
#include "qpainter.h"
#include "qevent.h"
#include "qdatetime.h"
#include "qdebug.h"

namespace OfUI {

	LunarCalendarItem::LunarCalendarItem(QWidget *parent) : QWidget(parent)
	{
		hover = false;
		pressed = false;
		listDayName << "*" << "初一" << "初二" << "初三" << "初四" << "初五" << "初六" << "初七" << "初八" << "初九" << "初十"
			<< "十一" << "十二" << "十三" << "十四" << "十五" << "十六" << "十七" << "十八" << "十九" << "二十"
			<< "廿一" << "廿二" << "廿三" << "廿四" << "廿五" << "廿六" << "廿七" << "廿八" << "廿九" << "三十";

		select = false;
		showLunar = true;
		bgImage = ":/image/bg_calendar.png";
		selectType = SelectType_Rect;

		date = QDate::currentDate();
		lunar = "初一";
		dayType = DayType_MonthCurrent;

		borderColor = QColor(180, 180, 180);
		weekColor = QColor(255, 0, 0);
		superColor = QColor(255, 129, 6);
		lunarColor = QColor(55, 156, 238);

		currentTextColor = QColor(0, 0, 0);
		otherTextColor = QColor(200, 200, 200);
		selectTextColor = QColor(255, 255, 255);
		hoverTextColor = QColor(250, 250, 250);

		currentLunarColor = QColor(150, 150, 150);
		otherLunarColor = QColor(200, 200, 200);
		selectLunarColor = QColor(255, 255, 255);
		hoverLunarColor = QColor(250, 250, 250);

		currentBgColor = QColor(255, 255, 255);
		otherBgColor = QColor(240, 240, 240);
		selectBgColor = QColor(208, 47, 18);
		hoverBgColor = QColor(204, 183, 180);
	}

	void LunarCalendarItem::enterEvent(EnterEvent *)
	{
		hover = true;
		this->update();
	}

	void LunarCalendarItem::leaveEvent(QEvent *)
	{
		hover = false;
		this->update();
	}

	void LunarCalendarItem::mousePressEvent(QMouseEvent *)
	{
		pressed = true;
		this->update();

		Q_EMIT clicked(date, dayType);
	}

	void LunarCalendarItem::mouseReleaseEvent(QMouseEvent *)
	{
		pressed = false;
		this->update();
	}

	void LunarCalendarItem::paintEvent(QPaintEvent *)
	{
		//绘制准备工作,启用反锯齿
		QPainter painter(this);
		painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

		//绘制背景和边框
		drawBg(&painter);

		//优先绘制选中状态,其次绘制悬停状态
		if (select) {
			drawBgCurrent(&painter, selectBgColor);
		}
		else if (hover) {
			drawBgCurrent(&painter, hoverBgColor);
		}

		//绘制日期
		drawDay(&painter);

		//绘制农历信息
		drawLunar(&painter);
	}

	void LunarCalendarItem::drawBg(QPainter *painter)
	{
		painter->save();

		//根据当前类型选择对应的颜色
		QColor bgColor = currentBgColor;
		if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
			bgColor = otherBgColor;
		}

		painter->setPen(borderColor);
		painter->setBrush(bgColor);
		painter->drawRect(rect());

		painter->restore();
	}

	void LunarCalendarItem::drawBgCurrent(QPainter *painter, const QColor &color)
	{
		int width = this->width();
		int height = this->height();
		int side = qMin(width, height);

		painter->save();

		painter->setPen(Qt::NoPen);
		painter->setBrush(color);

		//根据设定绘制背景样式
		if (selectType == SelectType_Rect) {
			painter->drawRect(rect());
		}
		else if (selectType == SelectType_Circle) {
			int radius = side / 2 - 3;
			painter->drawEllipse(QPointF(width / 2, height / 2), radius, radius);
		}
		else if (selectType == SelectType_Triangle) {
			int radius = side / 3;
			QPolygon pts;
			pts.setPoints(3, 1, 1, radius, 1, 1, radius);
			painter->drawRect(rect());
			painter->setBrush(superColor);
			painter->drawConvexPolygon(pts);
		}
		else if (selectType == SelectType_Image) {
			//等比例缩放居中绘制
			QImage img(bgImage);
			if (!img.isNull()) {
				img = img.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
				int x = (width - img.width()) / 2;
				int y = (height - img.height()) / 2;
				painter->drawImage(x, y, img);
			}
		}

		painter->restore();
	}

	void LunarCalendarItem::drawDay(QPainter *painter)
	{
		int width = this->width();
		int height = this->height();
		int side = qMin(width, height);

		painter->save();

		//根据当前类型选择对应的颜色
		QColor color = currentTextColor;
		if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
			color = otherTextColor;
		}
		else if (dayType == DayType_WeekEnd) {
			color = weekColor;
		}

		if (select) {
			color = selectTextColor;
		}
		else if (hover) {
			color = hoverTextColor;
		}

		painter->setPen(color);

		if (showLunar) {
			QFont font;
			font.setPixelSize(side / 2.7);
			painter->setFont(font);

			QRect dayRect = QRect(0, 0, width, height / 1.7);
			painter->drawText(dayRect, Qt::AlignHCenter | Qt::AlignBottom, QString::number(date.day()));
		}
		else {
			QFont font;
			font.setPixelSize(side / 2);
			painter->setFont(font);

			QRect dayRect = QRect(0, 0, width, height);
			painter->drawText(dayRect, Qt::AlignCenter, QString::number(date.day()));
		}

		painter->restore();
	}

	void LunarCalendarItem::drawLunar(QPainter *painter)
	{
		if (!showLunar) {
			return;
		}

		int width = this->width();
		int height = this->height();
		int side = qMin(width, height);

		painter->save();

		//判断当前农历文字是否节日,是节日且是当月则用农历节日颜色显示
		bool exist = (!listDayName.contains(lunar) && dayType != DayType_MonthPre && dayType != DayType_MonthNext);

		//根据当前类型选择对应的颜色
		QColor color = currentLunarColor;
		if (dayType == DayType_MonthPre || dayType == DayType_MonthNext) {
			color = otherLunarColor;
		}

		if (select) {
			color = selectTextColor;
		}
		else if (hover) {
			color = hoverTextColor;
		}
		else if (exist) {
			color = lunarColor;
		}

		painter->setPen(color);

		QFont font;
		font.setPixelSize(side / 5);
		painter->setFont(font);

		QRect lunarRect(0, height / 2, width, height / 2);
		painter->drawText(lunarRect, Qt::AlignCenter, lunar);

		painter->restore();
	}

	QSize LunarCalendarItem::sizeHint() const
	{
		return QSize(100, 100);
	}

	QSize LunarCalendarItem::minimumSizeHint() const
	{
		return QSize(20, 20);
	}

	bool LunarCalendarItem::getSelect() const
	{
		return this->select;
	}

	void LunarCalendarItem::setSelect(bool select)
	{
		if (this->select != select) {
			this->select = select;
			this->update();
		}
	}

	bool LunarCalendarItem::getShowLunar() const
	{
		return this->showLunar;
	}

	void LunarCalendarItem::setShowLunar(bool showLunar)
	{
		if (this->showLunar != showLunar) {
			this->showLunar = showLunar;
			this->update();
		}
	}

	QString LunarCalendarItem::getBgImage() const
	{
		return this->bgImage;
	}

	void LunarCalendarItem::setBgImage(const QString &bgImage)
	{
		if (this->bgImage != bgImage) {
			this->bgImage = bgImage;
			this->update();
		}
	}

	LunarCalendarItem::SelectType LunarCalendarItem::getSelectType() const
	{
		return this->selectType;
	}

	void LunarCalendarItem::setSelectType(const LunarCalendarItem::SelectType &selectType)
	{
		if (this->selectType != selectType) {
			this->selectType = selectType;
			this->update();
		}
	}

	QDate LunarCalendarItem::getDate() const
	{
		return this->date;
	}

	void LunarCalendarItem::setDate(const QDate &date)
	{
		if (this->date != date) {
			this->date = date;
			this->update();
		}
	}

	QString LunarCalendarItem::getLunar() const
	{
		return this->lunar;
	}

	void LunarCalendarItem::setLunar(const QString &lunar)
	{
		if (this->lunar != lunar) {
			this->lunar = lunar;
			this->update();
		}
	}

	LunarCalendarItem::DayType LunarCalendarItem::getDayType() const
	{
		return this->dayType;
	}

	void LunarCalendarItem::setDayType(const LunarCalendarItem::DayType &dayType)
	{
		if (this->dayType != dayType) {
			this->dayType = dayType;
			this->update();
		}
	}

	void LunarCalendarItem::setDate(const QDate &date, const QString &lunar, const DayType &dayType)
	{
		this->date = date;
		this->lunar = lunar;
		this->dayType = dayType;
		this->update();
	}

	QColor LunarCalendarItem::getBorderColor() const
	{
		return this->borderColor;
	}

	void LunarCalendarItem::setBorderColor(const QColor &borderColor)
	{
		if (this->borderColor != borderColor) {
			this->borderColor = borderColor;
			this->update();
		}
	}


	QColor LunarCalendarItem::getWeekColor() const
	{
		return this->weekColor;
	}

	void LunarCalendarItem::setWeekColor(const QColor &weekColor)
	{
		if (this->weekColor != weekColor) {
			this->weekColor = weekColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getSuperColor() const
	{
		return this->superColor;
	}

	void LunarCalendarItem::setSuperColor(const QColor &superColor)
	{
		if (this->superColor != superColor) {
			this->superColor = superColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getLunarColor() const
	{
		return this->lunarColor;
	}

	void LunarCalendarItem::setLunarColor(const QColor &lunarColor)
	{
		if (this->lunarColor != lunarColor) {
			this->lunarColor = lunarColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getCurrentTextColor() const
	{
		return this->currentTextColor;
	}

	void LunarCalendarItem::setCurrentTextColor(const QColor &currentTextColor)
	{
		if (this->currentTextColor != currentTextColor) {
			this->currentTextColor = currentTextColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getOtherTextColor() const
	{
		return this->otherTextColor;
	}

	void LunarCalendarItem::setOtherTextColor(const QColor &otherTextColor)
	{
		if (this->otherTextColor != otherTextColor) {
			this->otherTextColor = otherTextColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getSelectTextColor() const
	{
		return this->selectTextColor;
	}

	void LunarCalendarItem::setSelectTextColor(const QColor &selectTextColor)
	{
		if (this->selectTextColor != selectTextColor) {
			this->selectTextColor = selectTextColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getHoverTextColor() const
	{
		return this->hoverTextColor;
	}

	void LunarCalendarItem::setHoverTextColor(const QColor &hoverTextColor)
	{
		if (this->hoverTextColor != hoverTextColor) {
			this->hoverTextColor = hoverTextColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getCurrentLunarColor() const
	{
		return this->currentLunarColor;
	}

	void LunarCalendarItem::setCurrentLunarColor(const QColor &currentLunarColor)
	{
		if (this->currentLunarColor != currentLunarColor) {
			this->currentLunarColor = currentLunarColor;
			this->update();
		}
	}


	QColor LunarCalendarItem::getOtherLunarColor() const
	{
		return this->otherLunarColor;
	}

	void LunarCalendarItem::setOtherLunarColor(const QColor &otherLunarColor)
	{
		if (this->otherLunarColor != otherLunarColor) {
			this->otherLunarColor = otherLunarColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getSelectLunarColor() const
	{
		return this->selectLunarColor;
	}

	void LunarCalendarItem::setSelectLunarColor(const QColor &selectLunarColor)
	{
		if (this->selectLunarColor != selectLunarColor) {
			this->selectLunarColor = selectLunarColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getHoverLunarColor() const
	{
		return this->hoverLunarColor;
	}

	void LunarCalendarItem::setHoverLunarColor(const QColor &hoverLunarColor)
	{
		if (this->hoverLunarColor != hoverLunarColor) {
			this->hoverLunarColor = hoverLunarColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getCurrentBgColor() const
	{
		return this->currentBgColor;
	}

	void LunarCalendarItem::setCurrentBgColor(const QColor &currentBgColor)
	{
		if (this->currentBgColor != currentBgColor) {
			this->currentBgColor = currentBgColor;
			this->update();
		}
	}


	QColor LunarCalendarItem::getOtherBgColor() const
	{
		return this->otherBgColor;
	}

	void LunarCalendarItem::setOtherBgColor(const QColor &otherBgColor)
	{
		if (this->otherBgColor != otherBgColor) {
			this->otherBgColor = otherBgColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getSelectBgColor() const
	{
		return this->selectBgColor;
	}

	void LunarCalendarItem::setSelectBgColor(const QColor &selectBgColor)
	{
		if (this->selectBgColor != selectBgColor) {
			this->selectBgColor = selectBgColor;
			this->update();
		}
	}

	QColor LunarCalendarItem::getHoverBgColor() const
	{
		return this->hoverBgColor;
	}

	void LunarCalendarItem::setHoverBgColor(const QColor &hoverBgColor)
	{
		if (this->hoverBgColor != hoverBgColor) {
			this->hoverBgColor = hoverBgColor;
			this->update();
		}
	}

}